package com.shengdong.water.feature.signIn

import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.provider.Settings
import android.text.TextUtils
import android.util.Log
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.widget.AppCompatTextView
import androidx.core.app.ActivityCompat
import androidx.core.graphics.toColorInt
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.GridLayoutManager
import com.alibaba.android.arouter.facade.annotation.Route
import com.hjq.toast.Toaster
import com.kongzue.dialogx.dialogs.BottomDialog
import com.kongzue.dialogx.dialogs.MessageDialog
import com.kongzue.dialogx.dialogs.WaitDialog
import com.kongzue.dialogx.interfaces.DialogLifecycleCallback
import com.kongzue.dialogx.interfaces.OnBindView
import com.luck.picture.lib.basic.PictureSelector
import com.luck.picture.lib.config.SelectMimeType
import com.luck.picture.lib.entity.LocalMedia
import com.luck.picture.lib.interfaces.OnResultCallbackListener
import com.shengdong.water.R
import com.shengdong.water.base.BaseVMActivity
import com.shengdong.water.code.adapter.ImagePickerAdapter
import com.shengdong.water.code.bean.Province
import com.shengdong.water.code.config.RouterConfig
import com.shengdong.water.code.config.UserConfig
import com.shengdong.water.code.router.RouterManager
import com.shengdong.water.code.utils.CoilEngine
import com.shengdong.water.code.utils.FileUtil
import com.shengdong.water.code.utils.GridSpaceItemDecoration
import com.shengdong.water.code.utils.JsonUtil
import com.shengdong.water.code.utils.LocationUtil
import com.shengdong.water.code.utils.TimeUtil
import com.shengdong.water.code.utils.UploadUtil
import com.shengdong.water.code.viewmodel.SignInViewModel
import com.shengdong.water.code.widget.WheelView
import com.shengdong.water.databinding.ActivitySignInBinding
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import kotlin.collections.ArrayList
import kotlin.collections.MutableList
import kotlin.collections.MutableMap
import kotlin.collections.filter
import kotlin.collections.joinToString
import kotlin.collections.map
import kotlin.collections.mapOf
import kotlin.collections.mutableListOf
import kotlin.collections.mutableMapOf
import kotlin.collections.set
import kotlin.collections.toMutableList


@Route(path = RouterConfig.SIGN_PATH)
@AndroidEntryPoint
class SignActivity : BaseVMActivity<ActivitySignInBinding, SignInViewModel>() {

    override fun getLayoutId() = R.layout.activity_sign_in
    override fun getViewModelClass() = SignInViewModel::class.java

    override fun useImmersiveStatusBar(): Boolean = true
    override fun showStatusBar() = true

    private var dischargeOutletId = ""

    private val outletList: MutableList<String> = mutableListOf()
    private val imageLists: MutableList<String> = mutableListOf()
    private var isInRange = false // 是否在可签到范围内
    private val locationPermissions = arrayOf(
        Manifest.permission.ACCESS_FINE_LOCATION,
        Manifest.permission.ACCESS_COARSE_LOCATION
    )

    private val imageAdapter = ImagePickerAdapter()

    private var currentLat = 0.0
    private var currentLon = 0.0


    private val requestPermissionLauncher = registerForActivityResult(
        ActivityResultContracts.RequestMultiplePermissions()
    ) { permissions ->
        when {
            permissions.getOrDefault(Manifest.permission.ACCESS_FINE_LOCATION, false) -> {
                // 精确定位权限获取成功
                checkLocation()
            }
            permissions.getOrDefault(Manifest.permission.ACCESS_COARSE_LOCATION, false) -> {
                // 粗略定位权限获取成功
                checkLocation()
            }
            else -> {
                // 用户拒绝了权限
                Toaster.show("需要位置权限才能签到")
                binding.btnSign.isEnabled = false
            }
        }
    }


    override fun initViews() {
        RouterManager.inject(this)
        setTitle("运维签到")
        setRightText("签到记录")

        binding.viewModel = viewModel
        binding.monitorPictures.layoutManager = GridLayoutManager(this, 3)
        binding.monitorPictures.addItemDecoration(GridSpaceItemDecoration(spacing = 10))
        binding.monitorPictures.adapter = imageAdapter

        binding.tvSignUsername.setContent(UserConfig.user?.userName ?: "")
        binding.tvMobile.setContent(UserConfig.user?.phone ?: "")
        binding.tvSignDate.setContent(TimeUtil.getCurrentFormatTime())
        // 默认禁用签到按钮
        binding.btnSign.isEnabled = false
        // 检查并请求权限
        checkAndRequestPermissions()
        setupListener()


    }

    private fun checkAndRequestPermissions() {
        when {
            hasLocationPermissions() -> {
                // 已有权限,可以直接使用定位
                LocationUtil.init(this)
                checkLocation()
            }
            shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION) -> {
                // 用户之前拒绝过,需要解释原因
                showPermissionRationaleDialog()
            }
            else -> {
                // 请求权限
                requestPermissionLauncher.launch(locationPermissions)
            }
        }
    }

    private fun showPermissionRationaleDialog() {
        MessageDialog.build()
            .setTitle("需要定位权限")
            .setMessage("签到功能需要获取位置信息,请授予定位权限")
            .setOkButton("去设置") { dialog, v ->
                // 跳转到应用设置页面
                startActivity(Intent().apply {
                    action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
                    data = Uri.fromParts("package", packageName, null)
                })
                dialog.dismiss()
                false
            }
            .setCancelButton("取消") { dialog, v ->
                dialog.dismiss()
                Toaster.show("需要位置权限才能签到")
                binding.btnSign.isEnabled = false
                false
            }
            .show()
    }

    private fun hasLocationPermissions(): Boolean {
        return locationPermissions.all {
            ActivityCompat.checkSelfPermission(this, it) == PackageManager.PERMISSION_GRANTED
        }
    }

    private fun checkLocation(){
        if (!hasLocationPermissions()) {
            Toaster.show("需要位置权限才能签到")
            return
        }
//        if(TextUtils.isEmpty(dischargeOutletId)){
//            Toaster.show("请先选择排污口才能签到")
//            return
//        }
        LocationUtil.requestLocation (
            context = this,
//            outletLat = viewModel.outlets.value.find { it.id == dischargeOutletId }?.lat?.toDouble() ?: 0.0,
//            outletLon = viewModel.outlets.value.find { it.id == dischargeOutletId }?.lon?.toDouble() ?: 0.0,

            onLocationResult = { latitude, longitude ->
                // 处理位置信息
//                binding.tvLatLong.setContent("$latitude,$longitude")
//                binding.tvLatLong.setContentColor()
                currentLat = latitude
                currentLon = longitude
                binding.btnSign.isEnabled = false
//                val outletLat = viewModel.outlets.value.find { it.id == dischargeOutletId }?.lat?.toDouble() ?: 0.0
//                val outletLon = viewModel.outlets.value.find { it.id == dischargeOutletId }?.lon?.toDouble() ?: 0.0
//                val distance = LocationUtil.calculateDistance(outletLat, outletLon, latitude, longitude)
//                if (distance <= 500){
//                    isInRange = true
//                    binding.btnSign.isEnabled = true
//                }else {
//                    isInRange = false
//                    binding.btnSign.isEnabled = false
//                    Toaster.show("您不在排污口附近,请到指定位置签到")
//                }

            },
            onError = { msg ->
                // 处理错误
                binding.btnSign.isEnabled = false
                Toaster.show(msg)
                WaitDialog.dismiss()
            },
            onLoading = { msg ->
                // 显示加载
                WaitDialog.show(msg)
            },
            onLoadingDismiss = {
                // 隐藏加载
                WaitDialog.dismiss()
            }
        )
    }

    private fun setupListener() {

        binding.tvLatLong.setOnClickListener {
            //跳到经纬度页面
            RouterManager.build(RouterConfig.LATLONG_PATH).navigate(this, 10)
        }

        binding.tvPlace.setOnClickListener {
            //
            addressPickerDialog()
        }

        binding.tvOutlet.setOnClickListener {
            outletList.clear()
            optionPickerDialog()
        }

        imageAdapter.setOnAddClickListener {
            showBottomDialog()
        }



        binding.btnSign.setOnClickListener {
            handleSign()
        }
    }

    private fun handleSign(){
        if(TextUtils.isEmpty(dischargeOutletId)){
            Toaster.show("请先选择排污口才能签到")
            return
        }
        if(TextUtils.isEmpty(binding.tvCod.getContent())){
            Toaster.show("请填写COD/COD-Mn浓度")
            return
        }
        if(TextUtils.isEmpty(binding.tvAmmoniaNitrogen.getContent())){
            Toaster.show("请填写氨氮浓度")
            return
        }
        if(TextUtils.isEmpty(binding.tvPhosphorus.getContent())){
            Toaster.show("请填写总磷浓度")
            return
        }
        if(TextUtils.isEmpty(binding.tvNitrogen.getContent())){
            Toaster.show("请填写总氮浓度")
            return
        }
        if(TextUtils.isEmpty(binding.tvPh.getContent())){
            Toaster.show("请填写PH")
            return
        }
        if(TextUtils.isEmpty(binding.tvWaterTemperature.getContent())){
            Toaster.show("请填写水温")
            return
        }
        if(TextUtils.isEmpty(binding.tvOxygen.getContent())){
            Toaster.show("请填写溶解氧")
            return
        }
        if(TextUtils.isEmpty(binding.tvTurbidity.getContent())){
            Toaster.show("请填写浊度")
            return
        }
        if(TextUtils.isEmpty(binding.tvConductivity.getContent())){
            Toaster.show("请填写电导率")
            return
        }
        if(imageLists.isEmpty()){
            Toaster.show("请至少上传一张照片")
            return
        }
        if (!isInRange) {
            Toaster.show("请到排污口附近再签到")
            return
        }
        val signMap: MutableMap<String, Any> = mutableMapOf()
        signMap["checkInTime"] = binding.tvSignDate.getContent()
        signMap["dischargeOutletId"] = dischargeOutletId
        signMap["telphone"] = binding.tvMobile.getContent()
        signMap["createUser"] = UserConfig.user?.userId?.toInt() ?: 1
        signMap["remark"] = binding.remark.text.toString()
        signMap["figure"] = imageLists.joinToString(separator = ",")

        val fillMap = mapOf(
            "COD/COD-Mn浓度(mg/L)" to binding.tvCod.getContent(),
            "氨氮浓度(mg/L)" to binding.tvAmmoniaNitrogen.getContent(),
            "总磷浓度(mg/L)" to binding.tvPhosphorus.getContent(),
            "总氮浓度(mg/L)" to binding.tvNitrogen.getContent(),
            "PH" to binding.tvPh.getContent(),
            "水温(℃)" to binding.tvWaterTemperature.getContent(),
            "溶解氧(mg/L)" to binding.tvOxygen.getContent(),
            "浊度(ntu)" to binding.tvTurbidity.getContent(),
            "电导率(uS/cm)" to binding.tvConductivity.getContent()
        )
        signMap["fillIn"] = JsonUtil.mapToJson(fillMap)
        Log.e("签到参数", "$signMap")

        viewModel.submitSignIn(signMap)
    }


    private fun addressPickerDialog() {
        var provinceWheel: WheelView? = null
        var cityWheel: WheelView? = null
        var areaWheel: WheelView? = null
        BottomDialog.build().setDialogLifecycleCallback(object :
            DialogLifecycleCallback<BottomDialog>() {
            override fun onShow(dialog: BottomDialog?) {
                super.onShow(dialog)
            }

            override fun onDismiss(dialog: BottomDialog?) {
                super.onDismiss(dialog)
            }
        }

        ).setCustomView(object : OnBindView<BottomDialog>(R.layout.dialog_province) {
            override fun onBind(dialog: BottomDialog, v: View) {
                provinceWheel = v.findViewById(R.id.wheel_province)
                cityWheel = v.findViewById(R.id.wheel_city)
                areaWheel = v.findViewById(R.id.wheel_area)

                val provinceStr = FileUtil.readJsonFromAssets(this@SignActivity, "province.json")
                val provinceJson =
                    provinceStr?.let { JsonUtil.parseJsonToBean<MutableList<Province>>(it) }
                provinceWheel?.setDataItems(provinceJson?.map { it.name }?.toMutableList())
                provinceWheel?.setOnItemSelectedListener(object : WheelView.OnItemSelectedListener {
                    override fun onItemSelected(
                        wheelView: WheelView,
                        data: Any,
                        position: Int
                    ) {
                        // 切换城市
                        cityWheel?.setDataItems(provinceJson?.get(position)?.city?.map { it.name }
                            ?.toMutableList())

                        // 切换区域
                        val cityPosition = cityWheel?.getSelectedItemPosition()
                        areaWheel?.setDataItems(cityPosition?.let {
                            provinceJson?.get(position)?.city?.get(
                                it
                            )?.area
                        })
                    }

                })

                cityWheel?.setOnItemSelectedListener(object : WheelView.OnItemSelectedListener {
                    override fun onItemSelected(
                        wheelView: WheelView,
                        data: Any,
                        position: Int
                    ) {
                        // 切换区域
                        val provincePosition = provinceWheel?.getSelectedItemPosition()
                        areaWheel?.setDataItems(provincePosition?.let {
                            provinceJson?.get(it)?.city?.get(
                                position
                            )?.area
                        })
                    }
                })

                val tvConfirm = v.findViewById<AppCompatTextView>(R.id.tv_confirm)
                tvConfirm.setOnClickListener {
                    dialog.dismiss()
                    val province = provinceWheel?.getSelectedItemData()
                    val city = cityWheel?.getSelectedItemData()
                    val area = areaWheel?.getSelectedItemData()
                    binding.tvPlace.setContent("$province$city$area")
                    binding.tvPlace.setContentColor()
                }

                val tvCancel = v.findViewById<AppCompatTextView>(R.id.tv_cancel)
                tvCancel.setOnClickListener {
                    dialog.dismiss()
                }
            }
        }).setMaskColor("#66000000".toColorInt()).setAllowInterceptTouch(false).show()
    }


    private fun optionPickerDialog() {
        BottomDialog.build().setDialogLifecycleCallback(object :
            DialogLifecycleCallback<BottomDialog>() {
            override fun onShow(dialog: BottomDialog?) {
                super.onShow(dialog)
            }

            override fun onDismiss(dialog: BottomDialog?) {
                super.onDismiss(dialog)


            }
        }

        ).setCustomView(object : OnBindView<BottomDialog>(R.layout.dialog_outlet) {
            override fun onBind(dialog: BottomDialog, v: View) {
                val wheelView = v.findViewById<WheelView>(R.id.wheel_outlet)
                viewModel.outlets.value.map {
                    outletList.add(it.name)
                }
                wheelView.setDataItems(outletList)

                wheelView.setOnItemSelectedListener(object : WheelView.OnItemSelectedListener {
                    override fun onItemSelected(
                        wheelView: WheelView,
                        data: Any,
                        position: Int
                    ) {
                        dischargeOutletId = viewModel.outlets.value[position].id
                    }

                })

                val tvConfirm = v.findViewById<AppCompatTextView>(R.id.tv_confirm)
                tvConfirm.setOnClickListener {
                    dialog.dismiss()
                    binding.tvOutlet.setContent(viewModel.outlets.value.filter { it.id == dischargeOutletId }[0].tempName)
                    binding.tvOutlet.setContentColor()
                    if (hasLocationPermissions()) {
//                        checkLocation()
                        val outletLat = viewModel.outlets.value.find { it.id == dischargeOutletId }?.lat?.toDouble() ?: 0.0
                        val outletLon = viewModel.outlets.value.find { it.id == dischargeOutletId }?.lon?.toDouble() ?: 0.0
                        val distance = LocationUtil.calculateDistance(outletLat, outletLon, currentLat, currentLon)
                        if (distance <= 500){
                            isInRange = true
                            binding.btnSign.isEnabled = true
                        }else {
                            isInRange = false
                            binding.btnSign.isEnabled = false
                            Toaster.show("您不在排污口附近,请到指定位置签到")
                        }
                    } else {
                        checkAndRequestPermissions()
                    }
                }

                val tvCancel = v.findViewById<AppCompatTextView>(R.id.tv_cancel)
                tvCancel.setOnClickListener {
                    dialog.dismiss()
                }
            }
        }).setMaskColor("#66000000".toColorInt()).setAllowInterceptTouch(false).show()
    }





    private fun showBottomDialog() {
        BottomDialog.build().setDialogLifecycleCallback(object :
            DialogLifecycleCallback<BottomDialog>() {
            override fun onShow(dialog: BottomDialog?) {
                super.onShow(dialog)
            }

            override fun onDismiss(dialog: BottomDialog?) {
                super.onDismiss(dialog)
            }
        }

        ).setCustomView(object : OnBindView<BottomDialog>(R.layout.dialog_image_sheet) {
            override fun onBind(dialog: BottomDialog, v: View) {
                val alum = v.findViewById<AppCompatTextView>(R.id.tv_alum)
                val camera = v.findViewById<AppCompatTextView>(R.id.tv_camera)

                alum.setOnClickListener {
                    dialog.dismiss()
                    imageLists.clear()
                    openAlum()
                }
                camera.setOnClickListener {
                    dialog.dismiss()
                    imageLists.clear()
                    openCamera()
                }
                val tvCancel = v.findViewById<AppCompatTextView>(R.id.tv_cancel)
                tvCancel.setOnClickListener {
                    dialog.dismiss()
                }
            }
        }).setMaskColor("#66000000".toColorInt()).setAllowInterceptTouch(false).show()
    }

    private fun openAlum() {
        PictureSelector.create(this)
            .openGallery(SelectMimeType.ofImage())
            .setMaxSelectNum(9 - imageAdapter.itemCount + 1)
            .setImageEngine(CoilEngine())
            .forResult(object : OnResultCallbackListener<LocalMedia> {
                override fun onResult(result: ArrayList<LocalMedia>) {
                    result.map {
                        uploadImage(it)
                    }
                }

                override fun onCancel() {
                }

            })
    }

    private fun uploadImage(localMedia: LocalMedia) {
        try {
            val file = UploadUtil.getFileFromPath(this, localMedia.realPath)
            if (file != null) {
                val part = UploadUtil.createImagePart(file)
                viewModel.upLoadFile(part)
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }


    }

    private fun openCamera() {
        PictureSelector.create(this)
            .openCamera(SelectMimeType.ofImage())
            .forResult(object : OnResultCallbackListener<LocalMedia> {
                override fun onResult(result: ArrayList<LocalMedia>) {
                    result.map {
                        uploadImage(it)
                    }
                }

                override fun onCancel() {
                }

            })
    }

    override fun initData() {
        viewModel.getAllOutlets()
    }

    override fun observeData() {
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                launch {
                    viewModel.outlets.collect { outlets ->
                        if (outlets.isEmpty()) {
                            binding.tvOutlet.setContent("选择排污口")
                            return@collect
                        }
                    }
                }
                launch {
                    viewModel.uploadData.collect { result ->
                        if (result != null) {
                            imageLists.add(result.url)
                            imageAdapter.updateImages(result.url)
                        }
                    }
                }


                launch {
                    viewModel.finishActivity.collect { result ->
                        if (result) {
                            Toaster.show("签到成功")
                            RouterManager.navigate(RouterConfig.SignIn.SIGN_RECORD_PATH)
                            finish()
                        }
                    }

                }


            }
        }
    }


    override fun showLoading(loading: String) {
        WaitDialog.show(loading)
    }

    override fun dismissLoading() {
        super.dismissLoading()
        WaitDialog.dismiss()
    }


    override fun handleTitleBarRightClick() {
        RouterManager.navigate(RouterConfig.SignIn.SIGN_RECORD_PATH)
    }

    override fun handleBackPress() {

    }


    @Deprecated("Deprecated in Java")
    override fun onActivityResult(
        requestCode: Int,
        resultCode: Int,
        data: Intent?
    ) {
        super.onActivityResult(requestCode, resultCode, data)
        Log.e("onActivityResult", "$resultCode + $requestCode")
        when (resultCode) {
            RESULT_OK -> {
                when (requestCode) {
                    10 -> {
                        if (data != null) {
                            if (data.getStringExtra("longitude")
                                    .isNullOrEmpty() && data.getStringExtra("latitude")
                                    .isNullOrEmpty()
                            ) {
                                binding.tvLatLong.setContent("输入经纬度")
                                return
                            }
                            binding.tvLatLong.setContent(
                                "${data.getStringExtra("latitude")},${data.getStringExtra("longitude")}"
                            )
                            binding.tvLatLong.setContentColor()
                        }
                    }
                }
            }
        }
    }

}